package com.dis.service.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dis.pojo.entity.Permission;
import com.dis.pojo.entity.Role;
import com.dis.pojo.entity.RolePermission;
import com.dis.service.mapper.RoleMapper;
import com.dis.service.service.RoleService;
import com.dis.service.mapper.PermissionMapper;
import com.dis.service.mapper.RolePermissionMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public List<Role> getAllRoles() {
        return roleMapper.selectAll();
    }

    @Override
    public Role getRoleById(Long id) {
        Role role = roleMapper.selectById(id);
        if (role != null) {
            // 获取角色拥有的权限ID列表
            List<Long> permissionIds = rolePermissionMapper.selectPermissionIdsByRoleId(id);
            role.setPermissionIds(permissionIds);
        }
        return role;
    }

    @Override
    public boolean addRole(Role role) {
        return roleMapper.insert(role) > 0;
    }

    @Override
    public boolean updateRole(Role role) {
        return roleMapper.update(role) > 0;
    }

    @Override
    public boolean deleteRole(Long id) {
        // 先删除角色权限关联
        rolePermissionMapper.deleteByRoleId(id);
        // 再删除角色
        return roleMapper.deleteById(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignPermissions(Long roleId, List<Long> permissionIds) {
        try {
            // 1. 删除原有的权限关联
            int deleteCount = rolePermissionMapper.deleteByRoleId(roleId);
            log.info("删除角色ID={}的权限关联记录{}条", roleId, deleteCount);

            // 如果权限ID列表为空，则直接返回成功
            if (CollectionUtils.isEmpty(permissionIds)) {
                log.info("角色ID={}的权限列表为空，不添加新权限", roleId);
                return true;
            }

            // 2. 查询所有权限并构建父子映射关系
            Map<Long, List<Long>> parentChildMap = buildPermissionHierarchy();

            // 3. 获取需要分配的所有权限ID（包含父节点）
            Set<Long> allPermissionIds = new HashSet<>();
            for (Long permissionId : permissionIds) {
                // 添加当前权限及其所有父权限
                addPermissionWithParents(permissionId, allPermissionIds, parentChildMap);
            }

            // 4. 批量新增权限关联
            List<RolePermission> rolePermissions = new ArrayList<>();
            for (Long pid : allPermissionIds) {
                RolePermission rp = new RolePermission();
                rp.setRoleId(roleId);
                rp.setPermissionId(pid);
                rolePermissions.add(rp);
            }

            int insertCount = rolePermissionMapper.batchInsert(rolePermissions);
            log.info("为角色ID={}添加{}条权限关联记录（包含父权限）", roleId, insertCount);

            return insertCount > 0;
        } catch (Exception e) {
            log.error("为角色分配权限失败", e);
            throw e;
        }
    }

    // 构建权限父子关系映射
    private Map<Long, List<Long>> buildPermissionHierarchy() {
        // 查询所有权限（假设已注入permissionMapper）
        List<Permission> allPermissions = permissionMapper.selectAll();

        // 构建映射：父ID -> 子ID列表
        Map<Long, List<Long>> hierarchy = new HashMap<>();
        for (Permission p : allPermissions) {
            if (p.getParentId() != null && p.getParentId() != 0) {
                hierarchy.computeIfAbsent(p.getParentId(), k -> new ArrayList<>())
                        .add(p.getId());
            }
        }
        return hierarchy;
    }

    // 递归添加权限及其父权限
    private void addPermissionWithParents(Long permissionId, Set<Long> result, Map<Long, List<Long>> hierarchy) {
        // 添加当前权限
        result.add(permissionId);

        // 查找当前权限的父权限
        Optional<Permission> permissionOpt = Optional.ofNullable(permissionMapper.selectById(permissionId));
        if (!permissionOpt.isPresent()) return;

        Permission permission = permissionOpt.get();
        Long parentId = permission.getParentId();

        // 递归添加父权限（父ID存在且非根节点）
        if (parentId != null && parentId != 0) {
            addPermissionWithParents(parentId, result, hierarchy);
        }
    }
}